import javax.xml.bind.annotation.XmlType;
import java.lang.reflect.Array;
import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: wx
 * Date: 2023-09-11
 * Time: 23:50
 */
public class MyArrayList implements ITest {


    public int[] array ; //定义一个数组；
    public int usedsize;//确实数组的宽度；
    public static final int DEFAULT_SIZE = 10;


    /**
     *重写 MyArrayList,一个构造方法
     */
    public  MyArrayList() {
       this.array = new int[DEFAULT_SIZE];//代表顺序表的默认大小；
    }
    public MyArrayList(int capacity) {
        this.array = new int[capacity];
    }

    /**
     * 遍历顺序表的元素
     */
    @Override
    public void display() {
        for (int i = 0; i <this.usedsize; i++) {
            System.out.print(this.array[i]+" ");
        }
        System.out.println();
    }

    /**
     * 新增元素
     * @param data
     */
    @Override
    public void add(int data) {
        checkcCapacity();

        this.array[this.usedsize] = data;
        this.usedsize++;
    }


    @Override
    public boolean Isfull() {
       /* if(usedsize == array.length) {
            return true;
        }
        return false;*/
        return usedsize == array.length;
    }


    /**
     * 不是提供给用户去用的，这个方法只为当前类方法服务，所以需要封装起来；
     * 用来扩容的方法
     */
    private void checkcCapacity() {
        if (Isfull()) {
            //扩容
            array = Arrays.copyOf(array,array.length*2);
        }
    }



    /**
     * 指定位置放元素；
     * @param pos
     * @param data
     */
    @Override
    public void add(int pos, int data) {
        try {
            poscheckadd(pos);
        }catch(PosWrongful e) {
            e.printStackTrace();
            return;
        }

        checkcCapacity();

        //当i到pos就结束,从最后一个有效的数字往后移动，当i下标到pos就结束
        for (int i = usedsize-1; i <= pos ; i--) {
            array[i+1] = array[i];
        }

        //存放元素到pos位置
        array[pos] = data;
        //让usedsize++
        usedsize++;
    }


    /**
     *检查 pos 是否合法 ，但是如果日志打印的太多了，我们可能忽略了这个方法
     * 最好的方式就是引入一个异常，让异常去报错，那样就很容易观察了
     */
    private void poscheckadd(int pos) {
        if(pos<0 || pos>usedsize) {
            System.out.println("不合法");
            throw new PosWrongful("插入元素下标异常" + pos);
        }
    }
    @Override
    public boolean contains(int toFind) {
        //先判断是否为0，为0则直接返回不用查找；
        if (IsEmpty()){
            //如果查找引用数据类型 一定记住 重写方法
            return false;
        }
        for (int i = 0; i < usedsize; i++) {
            if(array[i]==array[toFind]){
                return true;
            }
        }
        return false;
    }

    @Override//判断usedsize是否为空
    public boolean IsEmpty() {
        return usedsize == 0;
    }

    @Override
    public int indexOf(int toFind) {
        if (IsEmpty()){
            //如果查找引用数据类型 一定记住 重写方法用equals
            return -1;
        }
        for (int i = 0; i < usedsize; i++) {
            if(array[i]==array[toFind]){
                return i;
            }
        }
        return -1;
    }

    @Override
    public int get(int pos) {
        checkSetAndSet(pos);
        if(IsEmpty()){
            throw new MyArrayListEmpty("获取指定下标元素时"+"顺序表为空");
        }
        return array[pos];
    }
    private void checkSetAndSet(int pos)throws MyArrayListEmpty {
        if(pos<0 || pos>=usedsize) {
            System.out.println("不合法");
            throw new MyArrayListEmpty("获取指令下标的元素异常" + pos);
        }
    }
    @Override//更新
    public void set(int pos, int value) {
        checkSetAndSet(pos);
        array[pos] = value;
    }

    @Override//删除
    public void remove(int toRemove) {
        int index = indexOf(toRemove);
        if (index==-1) {
            return;
        }
        for (int i = index; i < usedsize - 1; i++) {
            array[i] = array[i+1];
        }
        usedsize--;
    }

    @Override
    public int size() {
        return this.usedsize;
    }

    @Override
    public void clear() {
        this.usedsize=0;//基本简单类型直接置零；
        //原来是一个int类型数组，如果里边是引用数据类型的数组，这样置零会有内存泄露。基本数据类型
        //如果是引用数据类型建议用for循环进行置空；
        /*for (int i = 0; i <usedsize ; i++) {
            array[i]= Integer.parseInt(null);
        }*/
    }


}
